/*
 Copyright 2011 and onwards Joao C. R. Pereira

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
*/

#include "Memory.h"
#include "BinaryFile.h"

BinaryFile BinaryFile_New(string filename, int bufferSize) {
  
  BinaryFile bf = NewObj(BinaryFileObj);

  STARTSAFEPOINT(bf);
  
  bf->fname = String_Clone(filename);
  bf->file = NULL;
  bf->isOpen = false;
  bf->bufferSize = bufferSize;
  
  CHECKSAFEPOINTS(bf);
    
  return bf;
}

bool BinaryFile_OpenRead(BinaryFile bf) {
  
  CHECKSAFEPOINTS(bf);
  

  bf->file = fopen(bf->fname, "rb");

  if (bf->file == NULL) { return false; }
  bf->isOpen = true;

  long size = BinaryFile_GetSize(bf);
  if (bf->bufferSize > size) {
    bf->bufferSize = size;
  }
  bf->buffer = Buffer_New(bf->bufferSize, 0);
  setbuffer(bf->file, bf->buffer->bytes, bf->bufferSize);
  
  CHECKSAFEPOINTS(bf);
  return true;
}

long BinaryFile_GetSize(BinaryFile bf) {
  
  CHECKSAFEPOINTS(bf);
  Assert_IsTrue(bf->isOpen);
  
  long size;
  
  Assert_IsTrue(fseek(bf->file, 0L, SEEK_END) == 0);

  size = ftell(bf->file);

  Assert_IsTrue(fseek(bf->file, 0L, SEEK_SET) == 0);
  
  CHECKSAFEPOINTS(bf);
  return size;
}


bool BinaryFile_FillBuffer(BinaryFile bf, Buffer buffer, const size_t numBytes) {  
  
  CHECKSAFEPOINTS(bf);
  Assert_IsTrue(bf->isOpen);
  Assert_NotNull(buffer);
  
  Buffer_EnsureCapacity(buffer, numBytes);
  
  size_t numRead = fread(buffer->bytes, 1, numBytes, bf->file);
  CHECKSAFEPOINTS(buffer);  
  buffer->len = numBytes;
  CHECKSAFEPOINTS(bf);
  return (numRead == numBytes);
}




